Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)

您所在的位置:网站首页 我的世界 建筑生成 Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)

Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)

2024-06-21 06:28| 来源: 网络整理| 查看: 265

如果你学习过我们之前在1.12.2的建筑生成教程,那么对本次的教程的理解可能会相对轻松。 往期回顾

Minecraft 1.12.2模组开发(十四) 建筑生成 (structure generation) Minecraft 1.12.2模组开发(二十二) 多种建筑生成

我们本次将在1.16.5版本中实现建筑的自动生成。 1.首先我们需要生成一个建筑的.nbt文件 创建一个新世界

通过命令让我们获得一个建筑方块:

/give @s minecraft:structure_block

cr0.png

之后我们建造一个建筑

cr1.png

通过对建筑操作的坐标变换,将我们这个建筑完全包裹在区域内:

cr2.png

点击’Save’,建筑成功保存下来

cr3.png

保存的建筑会生成一个.nbt文件,我们需要将这个文件找到,路径为 开发包\run\saves\1_8version_test(你的存档名称)\generated\minecraft\structures 2.在data包中新建structures文件夹,将生成的.nbt文件放入其中。

cr4.png

3.在worldgen文件夹中新建template_pool(建筑模板库)文件夹 -> 新建一个与我们建筑名称对应的文件夹(以tank1为例) -> 在tank1中新建一个start_pool.json文件 在start_pool.json中编写: { "name": "re8joymod:tank1/start_pool", //格式:模组名:建筑名称/start_pool的文件路径 "fallback": "minecraft:empty", "elements": [ { "weight": 1, "element": { "location": "re8joymod:tank1", //格式:模组名:建筑名称 "processors": "minecraft:empty", "projection": "rigid", "element_type": "minecraft:single_pool_element" } } ] } 4.在common文件夹下新建 world文件夹 -> world文件夹中新建structure文件夹 -> structure文件夹中新建 structures文件夹 -> structures中新建一个建筑物类(以Tank1Structure.java为例)

cr5.png

在Tank1Structure.java中编写: package com.joy187.re8joymod.common.world.structure.structures; import com.google.common.collect.ImmutableList; import com.mojang.serialization.Codec; import net.minecraft.entity.EntityType; import net.minecraft.util.SharedSeedRandom; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MutableBoundingBox; import net.minecraft.util.math.vector.Vector3i; import net.minecraft.util.registry.Registry; import net.minecraft.world.IBlockReader; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.MobSpawnInfo; import net.minecraft.world.biome.provider.BiomeProvider; import net.minecraft.world.gen.ChunkGenerator; import net.minecraft.world.gen.GenerationStage; import net.minecraft.world.gen.Heightmap; import net.minecraft.world.gen.feature.NoFeatureConfig; import net.minecraft.world.gen.feature.jigsaw.JigsawManager; import net.minecraft.world.gen.feature.structure.*; import net.minecraft.util.registry.DynamicRegistries; import net.minecraft.world.gen.feature.template.TemplateManager; import net.minecraft.block.BlockState; import net.minecraft.util.ResourceLocation; import com.joy187.re8joymod.Utils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import java.util.List; public class Tank1Structure extends Structure { public Tank1Structure(Codec codec) { super(codec); } @Override public IStartFactory getStartFactory() { return Tank1Structure.Start::new; } @Override public GenerationStage.Decoration step() { return GenerationStage.Decoration.SURFACE_STRUCTURES; } private static final List STRUCTURE_MONSTERS = ImmutableList.of( new MobSpawnInfo.Spawners(EntityType.ILLUSIONER, 10, 1, 4), new MobSpawnInfo.Spawners(EntityType.VINDICATOR, 10, 1, 4) ); private static final List STRUCTURE_CREATURES = ImmutableList.of( new MobSpawnInfo.Spawners(EntityType.SHEEP, 10, 1, 5), new MobSpawnInfo.Spawners(EntityType.RABBIT, 10, 1, 4) ); @Override public List getDefaultSpawnList() { return STRUCTURE_MONSTERS; } @Override public List getDefaultCreatureSpawnList() { return STRUCTURE_CREATURES; } @Override protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeProvider biomeSource, long seed, SharedSeedRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoFeatureConfig featureConfig) { BlockPos centerOfChunk = new BlockPos((chunkX piece.move(0, 1, 0)); this.pieces.forEach(piece -> piece.getBoundingBox().y0 -= 1); // Since by default, the start piece of a structure spawns with it's corner at centerPos // and will randomly rotate around that corner, we will center the piece on centerPos instead. // This is so that our structure's start piece is now centered on the water check done in isFeatureChunk. // Whatever the offset done to center the start piece, that offset is applied to all other pieces // so the entire structure is shifted properly to the new spot. Vector3i structureCenter = this.pieces.get(0).getBoundingBox().getCenter(); int xOffset = centerPos.getX() - structureCenter.getX(); int zOffset = centerPos.getZ() - structureCenter.getZ(); for(StructurePiece structurePiece : this.pieces){ structurePiece.move(xOffset, 0, zOffset); } this.calculateBoundingBox(); //用作Debug,查看建筑生成的位置 LogManager.getLogger().log(Level.DEBUG, "Rundown House at " + this.pieces.get(0).getBoundingBox().x0 + " " + this.pieces.get(0).getBoundingBox().y0 + " " + this.pieces.get(0).getBoundingBox().z0); } } } 5.在刚刚新建的 structure文件夹中新建 ModStructure.java 在ModStructure.java中编写: package com.joy187.re8joymod.common.world.structure; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.joy187.re8joymod.Utils; import com.joy187.re8joymod.common.world.structure.structures.Tank1Structure; import net.minecraft.util.registry.WorldGenRegistries; import net.minecraft.world.gen.feature.NoFeatureConfig; import net.minecraft.world.gen.feature.structure.Structure; import net.minecraft.world.gen.settings.DimensionStructuresSettings; import net.minecraft.world.gen.settings.StructureSeparationSettings; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import java.util.HashMap; import java.util.Map; public class ModStructures { // STStructures.java public static final DeferredRegister> void setupMapSpacingAndLand( F structure, StructureSeparationSettings structureSeparationSettings, boolean transformSurroundingLand) { /* * We need to add our structures into the map in Structure class * alongside vanilla structures or else it will cause errors. * * If the registration is setup properly for the structure, * getRegistryName() should never return null. */ Structure.STRUCTURES_REGISTRY.put(structure.getRegistryName().toString(), structure); /* * Whether surrounding land will be modified automatically to conform to the bottom of the structure. * Basically, it adds land at the base of the structure like it does for Villages and Outposts. * Doesn't work well on structure that have pieces stacked vertically or change in heights. * * Note: The air space this method will create will be filled with water if the structure is below sealevel. * This means this is best for structure above sealevel so keep that in mind. * * NOISE_AFFECTING_FEATURES requires AccessTransformer (See resources/META-INF/accesstransformer.cfg) */ if(transformSurroundingLand){ Structure.NOISE_AFFECTING_FEATURES = ImmutableList.


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3